package system

import (
	"context"
	"gf-assistant/internal/common/consts"
	"gf-assistant/internal/common/factory"
	"gf-assistant/internal/system/parameter"
	"github.com/gogf/gf/v2/util/gconv"
	"reflect"
	"strings"
)

type MenuService struct{ menuDao string }

func init() {
	menuService := MenuService{
		menuDao: "system.MenuDao",
	}
	factory.Put(reflect.TypeOf(menuService).String(), &menuService)
}
func (s *MenuService) GetMenuDao() *MenuDao {
	return factory.Get(s.menuDao).(*MenuDao)
}
func (s *MenuService) ListMenu(ctx context.Context, req *parameter.ListMenuReq) (res *parameter.ListMenuRes) {
	menuInfoRes := s.GetMenuDao().ListMenu(ctx, req)
	return &parameter.ListMenuRes{
		Detail: menuInfoRes,
	}
}

// SaveMenu  创建菜单
func (s *MenuService) SaveMenu(ctx context.Context, req *parameter.SaveMenuReq) (res *parameter.SaveMenuRes) {

	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetMenuDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("菜单已经存在")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	menuIdNum := s.GetMenuDao().GetByMenuCode(ctx, req.ParentId, strings.TrimSpace(req.MenuCode))
	if req.MenuId > 0 {
		if menuIdNum > 1 {
			panic("菜单编码已存在！")
		}
		s.GetMenuDao().UpdateMenu(tx, req)
		res = &parameter.SaveMenuRes{MenuId: gconv.Uint(req.MenuId)}
	} else {
		if menuIdNum > 0 {
			panic("菜单编码已存在！")
		}
		res = s.GetMenuDao().CreateMenu(tx, req)
	}
	return res
}
func (s *MenuService) CreateRootMenu(ctx context.Context, req *parameter.CreateRootMenuReq) (res *parameter.CreateRootMenuRes) {
	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetMenuDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("菜单已经存在")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	menuId := s.GetMenuDao().GetByMenuCode(ctx, gconv.Uint(0), strings.TrimSpace(req.MenuCode))
	if menuId > 0 {
		panic("菜单编码已存在！")
	}
	s.GetMenuDao().CreateRootMenu(tx, req)
	return res
}
func (s *MenuService) DeleteMenu(ctx context.Context, req *parameter.DeleteMenuReq) (res *parameter.DeleteMenuRes) {
	if req.MenuId == 0 {
		panic("菜单ID必填")
	}
	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetMenuDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("菜单删除失败")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	s.GetMenuDao().DeleteMenu(tx, req)
	return res
}
func (s *MenuService) GetPermission(ctx context.Context, req *parameter.GetPermissionReq) (res *parameter.GetPermissionRes) {
	menuInfos := s.GetMenuDao().GetMenuTree(ctx, req)
	for _, v := range menuInfos {
		v.Checked = gconv.Bool(v.AuthState)
		v.Spread = true
	}
	menuInfos = s.getTreeRecursive(menuInfos, 0)
	return &parameter.GetPermissionRes{
		Detail: menuInfos,
	}
}
func (s *MenuService) getTreeRecursive(list []*parameter.PermissionTreeRes, pId uint) []*parameter.PermissionTreeRes {
	res := make([]*parameter.PermissionTreeRes, 0)
	for _, v := range list {
		if v.PId == pId {
			v.Children = s.getTreeRecursive(list, v.Id)
			res = append(res, v)
		}
	}
	return res
}
